package cn.bugstack.mybatis.binding;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import cn.bugstack.mybatis.session.SqlSession;
import cn.hutool.core.lang.ClassScanner;

/**
 * description: mapper注册机
 * taskId：
 * <pre>
 * change history:
 * date             defect#             person                comments
 * ---------------------------------------------------------------------
 * 2024/9/4       ********         zhaochaoyue        create file
 * </pre>
 *
 * @author: zhaochaoyue
 * @date: 2024/9/4 17:14
 * @copyright: 2024
 */
public class MapperRegistry {

    /**
     * 将已添加的映射器代理放入knowMappers中
     */
    private final Map<Class<?>,MapperProxyFactory<?>> knowMappers =new HashMap<>();
    
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>)knowMappers.get(type);
        if(mapperProxyFactory == null){
            throw new RuntimeException("type:"+type+" is not known to the MapperRegistry");
        }
        try {
            return mapperProxyFactory.newInstance(sqlSession);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("rror getting mapper instance. Cause: "+e,e);
        }
    }
    
    
    
    public <T> void addMapper(Class<T> type){
        //必须是接口才注册到mapper中
        if(type.isInterface()){
            //如果重复添加报错提示
            if(hasMapper(type)){
                throw new RuntimeException("type"+type+"is already know to the MapperRegistry.");
            }
            //注册映射代理工厂
            knowMappers.put(type,new MapperProxyFactory<>(type));
        }
    }

    private <T> boolean hasMapper(Class<T> type) {
        return knowMappers.containsKey(type);
    }
    
    public void addMappers(String packageName){
        //扫描包路径 调用 addMapper 创建映射代理类
        Set<Class<?>> classes = ClassScanner.scanPackage(packageName);
        for (Class<?> mapperClass : classes) {
            addMapper(mapperClass);
        }
    }
}
